/*
 *  Copyright 2015-2016, RenGu Technology (BeiJing) Co., Ltd.
 *  All right reserved.
 *
 *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED TO THIR PARTIES,
 *  COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 *  WITHOUT THE PRIOR WRITTEN PERMISSION OF RENGU TECHNOLOGY (BeiJing) CO., LTD.
 *
 *  AcctInfoMapperImpl
 *
 *  Edit History:
 *      lizhangtao Created on 2020年04月09日
 *
 */
package cc.rengu.igas.acct.common.dao.impl;

import cc.rengu.igas.acct.common.constant.AcctSqlMapperId;
import cc.rengu.igas.acct.common.dao.AcctInfoMapper;
import cc.rengu.igas.acct.common.dao.MapperCommon;
import cc.rengu.igas.acct.common.entity.AcctInfo;
import cc.rengu.igas.acct.common.enums.AcctRespCodeEnum;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.utility.util.DbsUtil;
import cc.rengu.utility.base.StringUtil;
import cc.rengu.utility.cache.UnifiedCache;
import cc.rengu.utility.dbs.Database;

/**
 * 账户表操作
 *
 * @author lizhangtao
 */
public class AcctInfoMapperImpl extends MapperCommon implements AcctInfoMapper {

    /**
     * 插入账户信息表
     *
     * @param acctInfo 账户信息表对应实体
     * @param dbs      数据库操作句柄
     * @return Database.DBS_SUCCESS成功，
     * Database.DBS_PKEY_DUPLICATE主键重复，
     * 违反唯一约束需要自己判断，其他失败
     * 为区别普通的数据库返回的应答码及异常，异常时返回Integer.MIN_VALUE
     */
    @Override
    public int insert2AcctInfo(AcctInfo acctInfo, DbsUtil dbs) {
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.INSERT2ACCT_INFO);
            int iReturnCode = dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, null);
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("登记账户信息失败,iReturnCode:<{}>", iReturnCode);
                return iReturnCode;
            }
            return Database.DBS_SUCCESS;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }

    /**
     * 插入账户信息表，数据库事务SQL执行
     *
     * @param acctInfo 账户信息表对应实体
     * @param dbs      数据库操作句柄
     * @return Database.DBS_SUCCESS成功，
     * Database.DBS_PKEY_DUPLICATE主键重复，
     * 违反唯一约束需要自己判断，其他失败
     * 为区别普通的数据库返回的应答码及异常，异常时返回Integer.MIN_VALUE
     */
    @Override
    public int insert2AcctInfoAndCommit(AcctInfo acctInfo, DbsUtil dbs) {
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.INSERT2ACCT_INFO);
            int iReturnCode = dbs.dbsExecuteSql(sqlStr, acctInfo, null);
            if (Database.DBS_SUCCESS != iReturnCode) {
                rglog.error("登记账户信息失败,iReturnCode:<{}>", iReturnCode);
                return iReturnCode;
            }
            return Database.DBS_SUCCESS;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }

    /**
     * 以账号查询账户信息表
     *
     * @param instId 法人机构号
     * @param acctNo 客户id
     * @param dbs    数据库操作句柄
     * @return 成功则返回账户信息实体对象，未查询到返回null
     * @throws BizException 其他失败抛出异常需要捕获处理
     */
    @Override
    public AcctInfo selectAcctInfoByAcctNo(String instId, String acctNo, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setAcctNo(acctNo);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.SELECT_ACCT_INFO_BY_ACCT_NO);
            int iReturnCode = dbs.dbsExecuteSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_ERROR.getRespCode(), AcctRespCodeEnum.DB_ERROR.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 以用户标识查询账户信息表
     *
     * @param instId   法人机构号
     * @param userType 外部用户类型
     * @param userId   用户标识
     * @param dbs      数据库操作句柄
     * @return 成功则返回账户信息实体对象，未查询到返回null
     * @throws BizException 其他失败抛出异常需要捕获处理
     */
    @Override
    public AcctInfo selectAcctInfoByUserId(String instId, String userType, String userId, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setUserType(userType);
            acctInfo.setUserId(userId);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.SELECT_ACCT_INFO_BY_USER_ID);
            int iReturnCode = dbs.dbsExecuteSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_ERROR.getRespCode(), AcctRespCodeEnum.DB_ERROR.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 以客户id查询账户信息表
     * 带事物提交，在传入数据库操作句柄开启事物时请勿使用
     *
     * @param customerId 客户id
     * @param instId     法人机构号
     * @param dbs        数据库操作句柄
     * @return 成功则返回账户信息实体对象，未查询到返回null
     * @throws BizException 其他失败抛出异常需要捕获处理
     */
    @Override
    public AcctInfo selectAcctInfoByCustomerId(String instId, String customerId, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setCustomerId(customerId);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.SELECT_ACCT_INFO_BY_CUSTOMER_ID);
            int iReturnCode = dbs.dbsExecuteSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_ERROR.getRespCode(), AcctRespCodeEnum.DB_ERROR.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 以客户号更新账户状态
     * 用于事物begin和end之间
     *
     * @param instId     法人机构号
     * @param customerId 客户号
     * @param acctStatus 需要更新的账户状态
     * @param dbs        数据库操作句柄
     * @return 成功返回Database.DBS_SUCCESS成功，其他失败
     * 为区别普通的数据库返回的应答码及异常，异常时返回Integer.MIN_VALUE
     */
    @Override
    public int updateAcctInfoStatusByCustomerId(String instId, String customerId, String acctStatus, DbsUtil dbs) {
        AcctInfo acctInfo = new AcctInfo();
        acctInfo.setInstId(instId);
        acctInfo.setCustomerId(customerId);
        acctInfo.setAcctStatus(acctStatus);
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.UPD_ACCT_INFO_BY_CUSTOMER_ID);
            return dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, acctInfo);
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }

    /**
     * 以客户号锁定需要更新的记录
     *
     * @param instId     法人机构号
     * @param customerId 客户号
     * @param dbs        数据库操作句柄
     * @return 成功返回账户信息，失败返回null
     * @throws BizException 其他数据库错误及异常抛出异常
     */
    @Override
    public AcctInfo lockAcctInfoByCustomerId(String instId, String customerId, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setCustomerId(customerId);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.LOCK_ACCT_INFO_BY_CUSTOMER_ID);
            int iReturnCode = dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 以外部用户类型及用户标识锁定需要更新的记录
     *
     * @param instId   法人机构号
     * @param userType 外部用户类型
     * @param userId   客户标识
     * @param dbs      数据库操作句柄
     * @return 成功返回账户信息，失败返回null
     * @throws BizException 其他数据库错误及异常抛出异常
     */
    @Override
    public AcctInfo lockAcctInfoByUserId(String instId, String userType, String userId, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setUserType(userType);
            acctInfo.setUserId(userId);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.LOCK_ACCT_INFO_BY_USER_ID);
            int iReturnCode = dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 以账号锁定需要更新的记录
     *
     * @param instId 法人机构号
     * @param acctNo 账号
     * @param dbs    数据库操作句柄
     * @return 成功返回账户信息，失败返回null
     * @throws BizException 其他数据库错误及异常抛出异常
     */
    @Override
    public AcctInfo lockAcctInfoByAcctNo(String instId, String acctNo, DbsUtil dbs) throws BizException {
        try {
            AcctInfo acctInfo = new AcctInfo();
            acctInfo.setInstId(instId);
            acctInfo.setAcctNo(acctNo);
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.LOCK_ACCT_INFO_BY_ACCT_NO);
            int iReturnCode = dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, acctInfo);
            if (Database.DBS_SUCCESS == iReturnCode) {
                return acctInfo;
            } else if (Database.DBS_NOT_FOUND == iReturnCode) {
                return null;
            } else {
                rglog.error("查询失败(非未查询到数据)");
                throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
            }
        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(AcctRespCodeEnum.DB_EXCEPTION.getRespCode(), AcctRespCodeEnum.DB_EXCEPTION.getRespDesc());
        }
    }

    /**
     * 冻结/冻结撤销
     *
     * @param instId 法人机构号
     * @param acctNo 账号
     * @param dbs    数据库操作句柄
     * @return 成功返回Database.DBS_SUCCESS成功，其他失败
     * 为区别普通的数据库返回的应答码及异常，异常时返回Integer.MIN_VALUE
     */
    @Override
    public int freezeAcctInfoByAcctNo(String instId, String acctNo, String availableBalance, String freezeBalance, DbsUtil dbs) {
        AcctInfo acctInfo = new AcctInfo();
        acctInfo.setInstId(instId);
        acctInfo.setAcctNo(acctNo);
        acctInfo.setAvailableBalance(availableBalance);
        acctInfo.setFreezeBalance(freezeBalance);
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.FREEZE_ACCT_INFO_BY_ACCT_NO);
            return dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, null);
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }

    /**
     * 解冻并借记
     *
     * @param instId        法人机构号
     * @param acctNo        账号
     * @param acctBalance   解冻并借记后账户余额
     * @param freezeBalance 解冻并借记后冻结余额
     * @param dbs           数据库句柄
     * @return 成功返回Database.DBS_SUCCESS
     * 其他为数据库返回应答码失败
     * 数据库异常时返回Integer.MIN_VALUE
     */
    @Override
    public int unfreezeAndDebitByAcctNo(String instId, String acctNo, String acctBalance, String freezeBalance, DbsUtil dbs) {
        AcctInfo acctInfo = new AcctInfo();
        acctInfo.setInstId(instId);
        acctInfo.setAcctNo(acctNo);
        acctInfo.setAcctBalance(acctBalance);
        acctInfo.setFreezeBalance(freezeBalance);
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.UNFREEZE_ACCT_INFO_BY_ACCT_NO);
            return dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, null);
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }

    /**
     * 正常借贷记更新账户余额
     * 扣减或者增加由外部完成，更新余额、可用余额及更新时间
     *
     * @param instId           法人机构号
     * @param acctNo           账号
     * @param balance          更新后余额
     * @param availableBalance 更新后可用余额
     * @param dbs              数据库句柄
     * @return 成功返回Database.DBS_SUCCESS成功
     * 其他为数据库返回应答码失败
     * 数据库异常时返回Integer.MIN_VALUE
     */
    @Override
    public int updAcctBalByAcctNo(String instId, String acctNo, String balance, String availableBalance, DbsUtil dbs) {
        AcctInfo acctInfo = new AcctInfo();
        acctInfo.setInstId(instId);
        acctInfo.setAcctNo(acctNo);
        acctInfo.setAcctBalance(balance);
        acctInfo.setAvailableBalance(availableBalance);
        try {
            String sqlStr = (String) UnifiedCache.get(AppParamConstant.SQL_MAPPER_CACHE, AcctSqlMapperId.UPD_ACCT_BAL_BY_ACCT_NO);
            return dbs.dbsExecuteTransactionSql(sqlStr, acctInfo, null);
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            return Integer.MIN_VALUE;
        }
    }
}
